package com.site.dao.impl.backend.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.site.dao.backend.system.RoleDao;
import com.site.dto.backend.system.RoleBizBean;
import com.site.model.backend.system.ResourseInfo;
import com.site.model.backend.system.RoleInfo;
import com.site.model.backend.system.UsersInfo;
import com.site.util.DateUtils;
import com.site.util.PropertyUtils;
import com.site.util.StringUtils;
import com.site.util.base.dao.BaseDaoImpl;
import com.site.util.base.dao.HQLHelper;
import com.site.util.constant.Constants;
import com.site.util.extremetable.QueryPage;

@Repository
public class RoleDaoImpl  extends BaseDaoImpl implements RoleDao {

	@Override
	public List<RoleInfo> getRoleList(QueryPage queryPage, RoleBizBean vo) {
		HQLHelper hqlHelper = new HQLHelper("RoleInfo");
		if(null != vo){
			if(!StringUtils.isEmpty(vo.getRoleName())){
				hqlHelper.addLike("roleName", vo.getRoleName());
			}
			if(null != vo.getId()){
				hqlHelper.addEqual("id", vo.getId());
			}
		}
		
		if(null != queryPage){
			return super.findByHQL(queryPage, hqlHelper.getHQL(), null);
		} else {
			return super.findByHQL(hqlHelper.getHQL(),null);
		}
	}

	@Override
	public void save(RoleBizBean obj) {
		if(null != obj){
			RoleInfo po = new RoleInfo();
			PropertyUtils.copyProperties(po, obj);
			super.save(po);
		}
	}

	@Override
	public void update(RoleBizBean roleBizBean) {
		if(null != roleBizBean){
			RoleInfo po = (RoleInfo)super.getEntityById(RoleInfo.class, roleBizBean.getId());
			if(null != po){
				PropertyUtils.copyNotNullProperties(po, roleBizBean);
			}
			super.update(po);
		}
	}

	@Override
	public List<UsersInfo> getRoleUsers(Long roleId) {
		List<UsersInfo> userInfoList = null;
		String sql = "SELECT u.user_id,u.USER_NAME,u.password,u.created_date,u.created_user,u.modified_date,u.updated_user,u.mark_delete,u.realname FROM m_system_role_user r JOIN m_system_users u ON r.USER_ID = u.user_id WHERE r.ROLE_ID = :roleId";
		if(null != roleId){
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("roleId", roleId);
			List<Object[]> users = (List<Object[]>)this.findBySQL(sql,params);
			if(null != users && users.size() > 0){
				userInfoList = new ArrayList<UsersInfo>();
				UsersInfo userInfo = null;
				for (Object[] user: users) {
					userInfo = new UsersInfo();
					userInfo.setUserId(Long.parseLong(user[0]+""));
					userInfo.setUserName(user[1]+"");
					userInfo.setPassWord(user[2]+"");
					userInfo.setCreatedDate(user[3]!=null?DateUtils.parseDate2(user[3].toString()):null);
					userInfo.setCreatedUser(user[4]!=null?user[4]+"":null);
					userInfo.setModifiedDate(user[5]!=null?DateUtils.parseDate2(user[5].toString()):null);
					userInfo.setUpdatedUser(user[6]!=null?user[6]+"":null);
					userInfo.setMarkDelete(user[7]!=null?user[7]+"":null);
					userInfo.setRealName(user[8]!=null?user[8]+"":null);
					userInfoList.add(userInfo);
				}
			}
		}
		return userInfoList;
	}

	@Override
	public RoleInfo getRoleByName(String roleName) {
		StringBuffer sql = new StringBuffer("select v.id,v.role_name from m_system_role v where v.role_name = :roleName");
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("roleName", roleName);
		List<Object[]> roles = (List<Object[]>)this.findBySQL(sql.toString(), params);
		
		if(null == roles || roles.size()==0) {
			return null;
		} else {
			 RoleInfo roleInfo = new RoleInfo();
			 roleInfo.setId(roles.get(0)[0] != null ? Long.parseLong(roles.get(0)[0]+""):null);
			 roleInfo.setRoleName(roles.get(0)[1] != null ? roles.get(0)[1].toString():null);
			 return roleInfo;
		}
	}

	@Override
	public void saveRoleUser(RoleBizBean obj) {
		
		if(null != obj && !StringUtils.isEmpty(obj.getUserIds()) && null != obj.getId()){
			String[] array = obj.getUserIds().split(",");
			if(null != array && array.length > 0){
				for (String string : array) {
					// 检查是否已经存在，如果已经存在不用增加
					List<Object[]> objectlist = super.findBySQL("select (1) from m_system_role_user m where m.user_id ="+string+" and m.role_id = "+obj.getId()+"");
					if(!(null != objectlist && objectlist.size() > 0))
						super.getCountBySQL("insert into m_system_role_user values("+string+","+obj.getId()+")");
				}	
			}
		}
	}

	@Override
	public void deleteRoleUser(RoleBizBean obj) {
		if(null != obj && !StringUtils.isEmpty(obj.getUserIds()) && null != obj.getId()){
			super.getCountBySQL("delete from m_system_role_user where user_id in ("+obj.getUserIds()+") and role_id = "+obj.getId());
		}
	}

	@Override
	public void enabled(Long obj) {
		if(null != obj){
			RoleInfo po = (RoleInfo)super.getEntityById(RoleInfo.class, obj);
			po.setMarkDelete(Constants.COMM_N);
			super.update(po);
		}
	}

	@Override
	public void saveRoleAuth(RoleBizBean obj) {
		if(null != obj && !StringUtils.isEmpty(obj.getAuthIds()) && null != obj.getId()){
			String[] array = obj.getAuthIds().split(",");
			if(null != array && array.length > 0){
				for (String string : array) {
					// 检查是否已经存在，如果已经存在不用增加
					List<Object[]> objectlist = super.findBySQL("SELECT (1) FROM m_system_role_authority m WHERE m.authority_id ="+string+" AND m.role_id = "+obj.getId());
					if(!(null != objectlist && objectlist.size() > 0))
						super.getCountBySQL("insert into m_system_role_authority values("+string+","+obj.getId()+")");
				}	
			}
		}
	}

	@Override
	public void deleteRoleAuth(RoleBizBean obj) {
		if(null != obj && !StringUtils.isEmpty(obj.getAuthIds()) && null != obj.getId()){
			if(null != obj && obj.getAuthIds().length() > 0){
				super.getCountBySQL("delete from m_system_role_authority where authority_id in("+obj.getAuthIds()+") and role_id = "+obj.getId());
			}
		}
	}

	@Override
	public List<ResourseInfo> getRoleResourse(Long roleId) {
		List<ResourseInfo> resourseInfoList = null;
		// 这个方法目前是没有用递归的，现在只有两级，如果已经多级 出现，这个就不能用
		String sql = "SELECT msr.`ID`,msr.`PID`,msr.`TITLE`,msr.`URL`,msr.ORDER_BY FROM `m_system_role_resource` msrr JOIN `m_system_resource` msr ON msrr.`RESOURCE_ID` = msr.`ID` AND msr.`MARK_DELETE` ='N' WHERE msrr.`ROLE_ID` = :roleId";
		if(null != roleId){
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("roleId", roleId);
			List<Object[]> resourseList = (List<Object[]>)this.findBySQL(sql,params);
			if(null != resourseList && resourseList.size() > 0){
				resourseInfoList = new ArrayList<ResourseInfo>();
				ResourseInfo resourseInfo = null;
				for (Object[] resourse: resourseList) {
					resourseInfo = new ResourseInfo();
					resourseInfo.setId(Long.parseLong(resourse[0]+""));
					if(null != resourse[1]){
						ResourseInfo v = new ResourseInfo();
						v.setId(Long.parseLong(resourse[1]+""));
						resourseInfo.setParentResourseInfo(v);
					}
					resourseInfo.setTitle(resourse[2]+"");
					resourseInfo.setUrl(resourse[3]+"");
					resourseInfo.setOrderBy(null == resourse[4]?null:Integer.valueOf(resourse[4]+""));
					resourseInfoList.add(resourseInfo);
				}
			}
		}
		
		List<ResourseInfo> resourseInfoList1 = new ArrayList<ResourseInfo>();
		if(null != resourseInfoList && resourseInfoList.size() > 0){
			for (ResourseInfo v1 : resourseInfoList) {
				if(null != v1){
					if(null != v1.getParentResourseInfo()){
						for (ResourseInfo resourseInfo : resourseInfoList1) {
							if(null != resourseInfo && resourseInfo.getId() == v1.getParentResourseInfo().getId()){
								if(null == resourseInfo.getChildrenList()){
									List<ResourseInfo> list = new ArrayList<ResourseInfo>();
									v1.setParentResourseInfo(resourseInfo);
									list.add(v1);
									resourseInfo.setChildrenList(list);
									break;
								} else {
									v1.setParentResourseInfo(resourseInfo);
									resourseInfo.getChildrenList().add(v1);
									break;
								}
							}
						}
					} else {
						resourseInfoList1.add(v1);
					}
				}
			}
		}
		
		return resourseInfoList1;
	}

	@Override
	public List<ResourseInfo> getNotRoleResourse(Long roleId) {
		// 这个方法目前是没有用递归的，现在只有两级，如果已经多级 出现，这个就不能用
		List<ResourseInfo> resourseInfoList = null;
		String sql ="SELECT msr.`ID`, msr.`PID`, msr.`TITLE` FROM `m_system_resource` msr WHERE msr.`MARK_DELETE` = 'N' AND msr.`ID` NOT IN(SELECT msrr.`RESOURCE_ID` FROM `m_system_role_resource` msrr WHERE msrr.`ROLE_ID` = :roleId) " +
				"UNION " +
				"SELECT msr.`ID`, msr.`PID`, msr.`TITLE` FROM `m_system_resource` msr WHERE msr.`MARK_DELETE` = 'N' AND msr.`ID` " +
				"IN (SELECT DISTINCT msr.`PID` FROM `m_system_resource` msr WHERE msr.`MARK_DELETE` = 'N' AND msr.`ID` NOT IN(SELECT msrr.`RESOURCE_ID` FROM `m_system_role_resource` msrr WHERE msrr.`ROLE_ID` = :roleId) AND msr.`PID` IS NOT NULL ) ORDER BY id" ;
		
		if(null != roleId){
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("roleId", roleId);
			List<Object[]> resourseList = (List<Object[]>)this.findBySQL(sql,params);
			if(null != resourseList && resourseList.size() > 0){
				resourseInfoList = new ArrayList<ResourseInfo>();
				ResourseInfo resourseInfo = null;
				for (Object[] resourse: resourseList) {
					resourseInfo = new ResourseInfo();
					resourseInfo.setId(Long.parseLong(resourse[0]+""));
					if(null != resourse[1]){
						ResourseInfo v = new ResourseInfo();
						v.setId(Long.parseLong(resourse[1]+""));
						resourseInfo.setParentResourseInfo(v);
					}
					resourseInfo.setTitle(resourse[2]+"");
					resourseInfoList.add(resourseInfo);
				}
			}
		}
		
		List<ResourseInfo> resourseInfoList1 = new ArrayList<ResourseInfo>();
		if(null != resourseInfoList && resourseInfoList.size() > 0){
			for (ResourseInfo v1 : resourseInfoList) {
				if(null != v1){
					if(null != v1.getParentResourseInfo()){
						for (ResourseInfo resourseInfo : resourseInfoList1) {
							if(null != resourseInfo && resourseInfo.getId() == v1.getParentResourseInfo().getId()){
								if(null == resourseInfo.getChildrenList()){
									List<ResourseInfo> list = new ArrayList<ResourseInfo>();
									v1.setParentResourseInfo(resourseInfo);
									list.add(v1);
									resourseInfo.setChildrenList(list);
									break;
								} else {
									v1.setParentResourseInfo(resourseInfo);
									resourseInfo.getChildrenList().add(v1);
									break;
								}
							}
						}
					} else {
						resourseInfoList1.add(v1);
					}
				}
			}
		}
		
		return resourseInfoList1;
	}

	@Override
	public void saveRoleMenu(RoleBizBean obj) {
		if(null != obj && !StringUtils.isEmpty(obj.getResourseIds()) && null != obj.getId()){
			String[] array = obj.getResourseIds().split(",");
			if(null != array && array.length > 0){
				for (String string : array) {
					// 查找当前资源的父亲id
					List<Object[]> objectPid = super.findBySQL("SELECT m.`PID` FROM `m_system_resource` m WHERE m.`ID` = "+string);
					
					if(null != objectPid && objectPid.size() > 0){
						
						String pid = String.valueOf(objectPid.get(0));
						List<Object[]> objectPidExt = super.findBySQL("select (1) from m_system_role_resource m where m.RESOURCE_ID ="+pid+" and m.role_id = "+obj.getId()+"");
						//	检查父资源是否已经存在，如果已经存在不用增加，反之
						if(!(null != objectPidExt && objectPidExt.size() > 0)){
							super.executeBySQL("insert into m_system_role_resource values("+pid+","+obj.getId()+")");
						}
						//	检查当前资源是否已经存在，如果已经存在不用增加
						List<Object[]> objectlist = super.findBySQL("select (1) from m_system_role_resource m where m.RESOURCE_ID ="+string+" and m.role_id = "+obj.getId()+"");
						if(!(null != objectlist && objectlist.size() > 0)){
							super.executeBySQL("insert into m_system_role_resource values("+string+","+obj.getId()+")");
						}
					}
				}	
			}
		}
	}

	@Override
	public void deleteRoleMenu(RoleBizBean obj) {
		if(null != obj && !StringUtils.isEmpty(obj.getResourseIds()) && null != obj.getId()){
			// 查找要删除资源的父资源id start 
			String sqlPid = "SELECT DISTINCT msr.pid FROM `m_system_resource` msr JOIN `m_system_role_resource` msrr ON msr.id = msrr.`RESOURCE_ID` WHERE msrr.`ROLE_ID` = "+obj.getId()+" AND msr.id IN ("+obj.getResourseIds()+")";
			List<Object[]> objectPid = super.findBySQL(sqlPid);
			
			// 把父id组装为'pid1,pid2,pid3'
			String tempPid = "";
			if(null != objectPid && objectPid.size() > 0){
				for (Object[] objects : objectPid) {
					if(null != objects[0]){
						tempPid += String.valueOf(objects[0])+",";
					}
				}
				// 排序，这里没有什么意义，就是为了去掉最后一个','
				if(!StringUtils.isEmpty(tempPid)){
					tempPid = StringUtils.sortAsStringWithComma(tempPid);
				}
			}
			// 查找要删除资源的父资源id end 
			
			// 判断当前资源是不是最后一个资源，如果是则把父亲资源删除，反之
			if(!StringUtils.isEmpty(tempPid)){
				
				String sqlExist = "SELECT DISTINCT msr.pid FROM `m_system_role_resource` msrr JOIN `m_system_resource` msr ON msrr.`RESOURCE_ID` = msr.id AND msrr.`ROLE_ID` = "+obj.getId()+" AND msrr.`RESOURCE_ID` NOT IN("+obj.getResourseIds()+") and msr.`PID` in ("+tempPid+")";
				List<Object[]> objectExistPid = super.findBySQL(sqlExist);
				if(null != objectExistPid && objectExistPid.size() > 0){
					// 如果选择某一个大类下的所有资源，那就删除整个大类，如果只删除某一个大类下的某一个子资源，则保留大类资源
					List<Long> array = StringUtils.splitToListByLong(tempPid);
					for (Object[] objects : objectExistPid) {
						if(null != objects[0]){
							if(array.contains(Long.valueOf(String.valueOf(objects[0])))){
								array.remove(Long.valueOf(String.valueOf(objects[0])));
							}
						}
					}
					
					if(null != array && array.size() > 0){
						// 需要删除的父资源id,以逗号间隔
						String pids = StringUtils.getStringByCommaLong(array);
						if(!StringUtils.isEmpty(pids)){
							super.getCountBySQL("delete from m_system_role_resource where RESOURCE_ID in ("+pids+","+obj.getResourseIds()+") and role_id = "+obj.getId());
						}
					} else {
						super.getCountBySQL("delete from m_system_role_resource where RESOURCE_ID in ("+obj.getResourseIds()+") and role_id = "+obj.getId());
					}
					
				} else {
					// 删除子资源并删除相应的父资源
					super.getCountBySQL("delete from m_system_role_resource where RESOURCE_ID in ("+tempPid+","+obj.getResourseIds()+") and role_id = "+obj.getId());
				}
			}
		}
	}

	@Override
	public List<RoleInfo> getUserRoles(Integer userId, QueryPage queryPage) {
		if(null != userId){
			
			String sql ="SELECT msr.`id`,msr.`role_name` FROM `m_system_role_user` msru JOIN `m_system_role` msr ON msru.`ROLE_ID` = msr.`id` AND msr.`mark_delete` = 'N' AND msru.`USER_ID` = :userId";
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("userId", userId);
			List<Object[]> roleList = null;
			if(null == queryPage){
				roleList = (List<Object[]>)this.findBySQL(sql,params);
			} else {
				roleList = (List<Object[]>)this.findBySQL(queryPage,sql,params);
			}
			
			if(null != roleList && roleList.size() > 0){
				List<RoleInfo> roleInfoList = new ArrayList<RoleInfo>();
				for (Object[] objects : roleList) {
					RoleInfo roleInfo = new RoleInfo();
					roleInfo.setId(Long.parseLong(objects[0]+""));
					roleInfo.setRoleName(objects[1]+"");
					roleInfoList.add(roleInfo);
				}
				return roleInfoList;
			}
		}
		return null;
	}

	@Override
	public RoleInfo getModel(RoleBizBean vo) {
		HQLHelper hqlHelper = new HQLHelper("RoleInfo");
		if(null != vo){
			if(!StringUtils.isEmpty(vo.getRoleName())){
				hqlHelper.addEqual("roleName", vo.getRoleName());
			}
		}
		hqlHelper.addEqual("markDelete", "N");
		List<RoleInfo> roleInfoList = super.findByHQL(hqlHelper.getHQL(), null);
		if(null != roleInfoList && roleInfoList.size() > 0){
			return roleInfoList.get(0);
		}
		return null;
	}

	@Override
	public List<ResourseInfo> getRoleResourse(String roleIds) {
		List<ResourseInfo> resourseInfoList = null;
		// 这个方法目前是没有用递归的，现在只有两级，如果已经多级 出现，这个就不能用
		String sql = "SELECT DISTINCT msr.`ID`,msr.`PID`,msr.`TITLE`,msr.`URL`,msr.`ORDER_BY` FROM `m_system_role_resource` msrr JOIN `m_system_resource` msr ON msrr.`RESOURCE_ID` = msr.`ID` AND msr.`MARK_DELETE` ='N' WHERE msrr.`ROLE_ID` IN ( :roleIds )";
		if(null != roleIds && !StringUtils.isEmpty(roleIds)){
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("roleIds", roleIds);
			List<Object[]> resourseList = (List<Object[]>)this.findBySQL(sql,params);
			if(null != resourseList && resourseList.size() > 0){
				resourseInfoList = new ArrayList<ResourseInfo>();
				ResourseInfo resourseInfo = null;
				for (Object[] resourse: resourseList) {
					resourseInfo = new ResourseInfo();
					resourseInfo.setId(Long.parseLong(resourse[0]+""));
					if(null != resourse[1]){
						ResourseInfo v = new ResourseInfo();
						v.setId(Long.parseLong(resourse[1]+""));
						resourseInfo.setParentResourseInfo(v);
					}
					resourseInfo.setTitle(null != resourse[2]?resourse[2]+"":null);
					resourseInfo.setUrl(null != resourse[3]?resourse[3]+"":null);
					resourseInfo.setOrderBy(null != resourse[4]?Integer.valueOf(resourse[4]+""):null);
					resourseInfoList.add(resourseInfo);
				}
			}
		}
		
		List<ResourseInfo> resourseInfoList1 = new ArrayList<ResourseInfo>();
		if(null != resourseInfoList && resourseInfoList.size() > 0){
			for (ResourseInfo v1 : resourseInfoList) {
				if(null != v1){
					if(null != v1.getParentResourseInfo()){
						for (ResourseInfo resourseInfo : resourseInfoList1) {
							if(null != resourseInfo && resourseInfo.getId() == v1.getParentResourseInfo().getId()){
								if(null == resourseInfo.getChildrenList()){
									List<ResourseInfo> list = new ArrayList<ResourseInfo>();
									v1.setParentResourseInfo(resourseInfo);
									list.add(v1);
									resourseInfo.setChildrenList(list);
									break;
								} else {
									v1.setParentResourseInfo(resourseInfo);
									resourseInfo.getChildrenList().add(v1);
									break;
								}
							}
						}
					} else {
						resourseInfoList1.add(v1);
					}
				}
			}
		}
		
		return resourseInfoList1;
	}

	@Override
	public void disabled(Long long1) {
		if(null != long1){
			RoleInfo po = (RoleInfo)super.getEntityById(RoleInfo.class, long1);
			po.setMarkDelete(Constants.COMM_Y);
			super.update(po);
		}
	}
}
